#!/usr/bin/env python
# -*- coding: utf-8 -*-

'''Builds both Tokyo Cabinet and the Python table driver on UNIX. Usage:

    # 1) Download Tokyo Cabinet
    wget http://voxel.dl.sourceforge.net/sourceforge/tokyocabinet/tokyocabinet-1.4.14.tar.gz
    
    # 2) Uncompress it
    tar -xzf tokyocabinet-1.4.14.tar.gz
    
    # 3) Install it to /usr
    sudo python install_tc.py tc
    
    # 4) You may also build the driver, but setup.py is recommended instead:
    python setup.py install      # recommended
    python install_tc.py driver  # deprecated
'''

from __future__ import absolute_import
# http://docs.python.org/whatsnew/pep-328.html

from __future__ import print_function   # deletes the print statement
from __future__ import unicode_literals # unicode by default

from subprocess import call
from sys import exit, prefix, version_info, argv
import os, os.path



class Path(str):
    @staticmethod
    def cwd():
        return Path(os.getcwd())
    
    def chdir(self):
        os.chdir(self)
    
    def child(self, *children):
        return self.__class__(os.path.join(self, *children))
    
    def absolute(self):
        return self.__class__(os.path.abspath(self))
    
    def exists(self):
        return os.path.exists(self)
    
    def mkdir(self, parents=False, mode=0777):
        if self.exists():
            return
        if parents:
            os.makedirs(self, mode)
        else:
            os.mkdir(self, mode)



PYTHON_VERSION = str(version_info[0]) + '.' + str(version_info[1])
DIR_INSTALL = Path('/usr')
DIR_MODULE = Path('.').absolute()
DIR_TC     = DIR_MODULE.child('tokyocabinet-1.4.14') # TC sources
DIR_BUILD  = DIR_MODULE.child('tcbuild')  # TC will be built here
DIR_DRIVER = DIR_MODULE.child('pykesto')  # driver sources
DIR_CURRENT= Path.cwd()

def call_or_exit(*a, **k):
    tip = k.pop('tip', None)
    ret = call(*a, **k)
    if ret:
        if tip: print(tip)
        exit(ret)

def build_tc():
    DIR_BUILD.mkdir(parents=True)
    DIR_TC.chdir()
    call_or_exit(['./configure', '--prefix=' + DIR_INSTALL],
        tip='Tip: to install dependencies on Ubuntu:\n    ' \
            'sudo apt-get install build-essential zlib1g-dev libbz2-dev\n' \
            '...then you can run this script again.')
    print('\nconfigure ok; running make')
    call_or_exit(['make'])
    print('\nlibtokyocabinet.so.8.3.0 compiled. Installing to ' + DIR_INSTALL)
    call_or_exit(['make', 'install'], tip='Tip: Are you root?')
    DIR_CURRENT.chdir()

def build_driver():
    print('Now build driver...')
    DIR_DRIVER.chdir()
    # Compile "tctable.c" into "tctable.o"
    call_or_exit('gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 ' \
            '-Wall -Wstrict-prototypes -fPIC -I{0}/include/python{2} ' \
            '-I{1}/include -c tctable.c -o tctable.o' \
            .format(prefix, DIR_INSTALL, PYTHON_VERSION),
            shell=True)
    print('\nLinking...\n')
    # Generate "tctable.so"
    call_or_exit('ld -shared {0}/lib/libtokyocabinet.so.8.3.0 tctable.o ' \
            '-o tctable.so'.format(DIR_INSTALL), shell=True)
    print('Done.')
    DIR_CURRENT.chdir()
    


if __name__ == '__main__':
    if len(argv) < 2:
        print(__doc__)
    elif argv[1] == 'tc':
        build_tc()      # TC should be installed separately (as root)
        print('Now you can install the Python driver:  python setup.py install')
    elif argv[1] == 'driver':
        # The driver may be installed as a common user
        build_driver()
    else:
        print('Argument not recognized: ' + argv[1])
